package com.tnsw.facebookautoliker;

import java.util.ArrayList;
import java.util.Hashtable;

import com.tnsw.coreutils.AsyncManager;
import com.tnsw.coreutils.MyLog;
import com.tnsw.coreutils.database.RecordBase;
import com.tnsw.coreutils.ui.BitmapCache;
import com.tnsw.coreutils.ui.ListViewPullUpdate;
import com.tnsw.coreutils.ui.UpdateView;
import com.tnsw.facebookautoliker.database.DBManager;
import com.tnsw.facebookautoliker.database.FriendsList;
import com.tnsw.facebookautoliker.helper.GeneralManager;
import com.tnsw.facebookautoliker.helper.command.GetPhoto;
import com.tnsw.facebookautoliker.services.AutoLikerService;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.Switch;
import android.widget.TextView;

public class FriendListAdapter extends BaseAdapter implements OnCheckedChangeListener {

	private String tag = "FriendListAdapter:" + this.toString();
	private Context context;
	private ListViewPullUpdate parentListView;
	private DBManager dbm;
	private GeneralManager gm;
	
	private LayoutInflater inflater = null;
	
	private ArrayList<RecordBase> arrFriends;
	private Drawable defaultSelector = null;
	
	private BitmapCache bCache;
	private Bitmap bmpAccept;
	private Bitmap bmpLike;
	
	public FriendListAdapter(Context context, ListViewPullUpdate parentListView) {
		this.context = context;
		
		this.parentListView = parentListView;
		
		this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		this.dbm = DBManager.getInstance(context);
		this.gm = GeneralManager.getInstance();
		
		this.arrFriends = new ArrayList<RecordBase>();
		
		this.refreshFromDB("");
		
		this.defaultSelector = this.parentListView.getSelector().getConstantState().newDrawable();		
		//this.bCache = new BitmapCache(10);
		
		this.bmpAccept = BitmapFactory.decodeResource(this.context.getResources(), R.drawable.fbfriend);
		this.bmpLike = BitmapFactory.decodeResource(this.context.getResources(), R.drawable.like_icon);
		MyLog.d(tag, "Constructor()");
	}
	
	public void setBitmapCache(BitmapCache bCache) {
		MyLog.d(tag, "bCache is set");
		
		this.bCache = bCache;
		
		if (this.bCache != null) { MyLog.d(tag, "this.bCache is not null"); }
		
	}
		
	public int updateRecord(FriendsList fl) {
		long startMil = System.currentTimeMillis();
		
		int position = -1;
		if (this.arrFriends == null) {
			this.arrFriends = new ArrayList<RecordBase>();
		}
		MyLog.d(tag, "updating record fl.name=" + fl.name + ", arrSize=" + this.arrFriends.size());
		
		int idx = this.findByName(fl.name);
		
		if (idx == -1) {  // Not exists, add it
			if (this.arrFriends.size() == 0) {
				this.arrFriends.add(fl);	
				
			} else {
				int length = this.arrFriends.size();
				int i;
				boolean b = true, isAdded = false;
				i = length-1;
				//for (i = length-1; i > -1; i--) {
				while (b) {
					int compare1 = -1;
					
					FriendsList r1 = (FriendsList) this.arrFriends.get(i);
					compare1 = fl.name.compareTo(r1.name);
					//MyLog.d(tag, "compare1=" + compare1 + ", r1=" + r1.name + ", fl=" + fl.name);
					if (compare1 > 0) {
						this.arrFriends.add(i+1, fl);
						MyLog.d(tag, "added fl.name=" + fl.name + " after " + r1.name);
						b = false;
						isAdded = true;
					}
					
					if ( (i > 0) && (b == true) ) {
						i -= 1;
					} else {
						b = false;
					}

				}
				
				if ( (i == 0) && (isAdded == false) ) {
					this.arrFriends.add(0, fl);
					MyLog.d(tag, "added fl.name=" + fl.name + " as first record");
					
				}
				
				position = i;
			}
			 
		} else {
			// name existed, do nothing
		}
		
		long endMil = System.currentTimeMillis();
		long elapsed = endMil-startMil;
		MyLog.d(tag, "elapsed=" + elapsed);
		return(position);
	}
	
	private int findByName(String name) {
		
		int length = this.arrFriends.size();
		
		if (length == 0) return(-1);  // Not found
		
		int i;
		for (i = 0; i < length; i++) {
			FriendsList fl = (FriendsList) this.arrFriends.get(i);
			if (fl.name.equals(name)) {
				return(i);
			}
		}
		
		return(-1);
	}
	
	public void refreshFromDB(String order) {
		if (this.arrFriends != null) {
			this.arrFriends.clear();	
		}
		
		String sql = "select * from friends_list order by name";
		if (order != null) {
			if (order.equals("") == false) {
				sql = "select * from friends_list order by " + order + " , name";
				MyLog.d(tag, "refreshFromDB(order=" + order + ")");
			}
		}
		
		this.arrFriends = dbm.getRecords("com.tnsw.facebookautoliker.database.FriendsList", sql, null, 0);
		this.updateToHash();
	}
	
	private void updateToHash() {
		if (this.arrFriends == null) return;
		if (this.arrFriends.size() == 0) return;
		
		AutoLikerService aService = AutoLikerService.getInstance();
		if (aService != null) {
			int len = this.arrFriends.size();
			int i;
			for (i = 0; i < len; i++) {
				FriendsList fl = (FriendsList) this.arrFriends.get(i);
				aService.updateFriendsList(fl.id, fl);
				
			}
		}
	}
	
	@Override
	public int getCount() {
		//MyLog.d(tag, "getCount()");
		if (this.arrFriends == null) {
			return(1);
		}
		
		if (this.arrFriends.size() == 0) {
			return(1);
		}
		
		//MyLog.d(tag, "here? size=" + this.arrFriends.size());
		return(this.arrFriends.size());
		
		
	}
	
	public int getPositionByName(String name) {
		int position = -1;
		
		if (this.arrFriends == null) {
			return(-1);
		}
		
		if (this.arrFriends.size() == 0) {
			return(-1);
		}
		
		int length = this.arrFriends.size();
		int i;
		for (i = 0; i < length; i++) {
			FriendsList fl = (FriendsList) this.arrFriends.get(i);
			if (fl.name.toLowerCase().contains(name.toLowerCase()) == true) {
				return(i);
			}
			
		}
		
		return(position);
	}

	@Override
	public Object getItem(int position) {

		if (this.arrFriends == null) return(null);
		
		return(this.arrFriends.get(position));
	}

	@Override
	public long getItemId(int position) {
		//MyLog.d(tag, "getItemId(" + position + ")");		
		return(position);
	}
	
	public void updateRecordById(String id, FriendsList fl) {
		if (this.arrFriends == null) return;
		int length = this.arrFriends.size();
		int i;
		for (i = 0; i < length; i++) {
			FriendsList f = (FriendsList) this.arrFriends.get(i);
			if (f.id.equals(fl.id)) {
				this.arrFriends.set(i, fl);
				break;
			}
		}
		
	}
	
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		//MyLog.d(tag, "adapter return position=" + position);
		boolean isEmpty = false;
		
		if (this.arrFriends == null) {
			isEmpty = true;
		} else if (this.arrFriends.size() == 0) {
			isEmpty = true;
		}
		
		if (isEmpty) {
			View v = (ViewGroup) this.inflater.inflate(R.layout.empty_pulldown, null);
			return(v);
		}
		
		FriendsList fl = (FriendsList) this.arrFriends.get(position);
		ViewGroup v = null;
		if (convertView == null) {
			v = (ViewGroup) this.inflater.inflate(R.layout.friends_list_item, null);
		} else {
			if (convertView.findViewById(R.id.tvFriendName) != null) {
				v = (ViewGroup) convertView;
			} else {
				v = (ViewGroup) this.inflater.inflate(R.layout.friends_list_item, null);
			}
		}
		
		TextView tvFriendName = (TextView) v.findViewById(R.id.tvFriendName);
		ImageView imgFriendPhoto = (ImageView) v.findViewById(R.id.imgFriendPhoto);
		ProgressBar pgLoadingImage = (ProgressBar) v.findViewById(R.id.pgLoadingImage);
		RelativeLayout layoutFriendListItem = (RelativeLayout) v.findViewById(R.id.layoutFriendListItem);
		Switch switchPush = (Switch) v.findViewById(R.id.switchPush);
		ImageView imgIsFriend = (ImageView) v.findViewById(R.id.imgIsFriend);
		
		TextView tvLikeForGuyCount = (TextView) v.findViewById(R.id.tvLikeForGuyCount);
		ImageView imgLike1 = (ImageView) v.findViewById(R.id.imgLike1);
		TextView tvLikeForGuyText = (TextView) v.findViewById(R.id.tvLikeForGuyText);
		
		TextView tvLikeInReturnCount = (TextView) v.findViewById(R.id.tvLikeInReturnCount);
		ImageView imgLike2 = (ImageView) v.findViewById(R.id.imgLike2);
		TextView tvLikeInReturnText = (TextView) v.findViewById(R.id.tvLikeInReturnText);
		
		tvLikeForGuyCount.setText(String.valueOf(fl.like_count));
		imgLike1.setImageBitmap(this.bmpLike);
		String gender = "this friend";
		if (fl.gender != null) {

			if (fl.gender.equals("") == false) {
				if (fl.gender.equals("female")) {
					gender = "her";
				} else if (fl.gender.equals("male")) {
					gender = "him";
				}
			}
		}
		
		tvLikeForGuyText.setText("for " + gender);
		imgLike1.setImageBitmap(this.bmpLike);
		imgLike2.setImageBitmap(this.bmpLike);
		imgLike1.setVisibility(View.VISIBLE);
		imgLike2.setVisibility(View.VISIBLE);
		
		if (fl.like_count > 0) {
			tvLikeForGuyCount.setVisibility(View.VISIBLE);
			tvLikeForGuyText.setVisibility(View.VISIBLE);
			imgLike1.setVisibility(View.VISIBLE);
		}
		
		if (fl.like_me_count > 0) {
			tvLikeInReturnCount.setText(" and " + String.valueOf(fl.like_me_count));
			//imgLike2.setImageBitmap(this.bmpLike);
			imgLike2.setVisibility(View.VISIBLE);
			tvLikeInReturnText.setText(" in return");
			tvLikeInReturnCount.setVisibility(View.VISIBLE);
			tvLikeInReturnText.setVisibility(View.VISIBLE);
		} else {
			imgLike2.setVisibility(View.GONE);
			tvLikeInReturnCount.setVisibility(View.GONE);
			tvLikeInReturnText.setVisibility(View.GONE);
		}
		
		if ( (fl.like_me_count == 0) && (fl.like_count == 0) ) {
			// never like each other
			tvLikeForGuyCount.setText("You've never liked each other");
			imgLike1.setVisibility(View.GONE);
			imgLike2.setVisibility(View.GONE);
			tvLikeForGuyText.setVisibility(View.GONE);
			tvLikeInReturnCount.setVisibility(View.GONE);
			tvLikeInReturnText.setVisibility(View.GONE);
		}
		
		
		if (fl.is_friend.equals("Y")) {
			imgIsFriend.setImageBitmap(this.bmpAccept);
			imgIsFriend.setVisibility(View.VISIBLE);
		} else {
			imgIsFriend.setVisibility(View.GONE);
		}
		
		if ( (fl.photo_path != null) ) {
			if (fl.photo_path.equals("") == false) {
				if (this.bCache == null) { MyLog.w(tag, "bCache is null!!"); }
				
				Bitmap bmp = this.bCache.getBitmap(fl.photo_path);
				if (bmp != null) {
					imgFriendPhoto.setVisibility(View.VISIBLE);
					pgLoadingImage.setVisibility(View.GONE);
					imgFriendPhoto.setImageBitmap(bmp);
					
				}
				
			}					
			
		} else {
			imgFriendPhoto.setImageBitmap(null);
			imgFriendPhoto.setVisibility(View.INVISIBLE);
			pgLoadingImage.setVisibility(View.VISIBLE);
			MyLog.e(tag, "Cannot find photo('" + fl.photo_path + "') for friend, id=" + fl.id + ", name=" + fl.name);
			GetPhoto gp = new GetPhoto(this.context, fl.id, fl.name);
			this.gm.addNewQueue(gp, 2);
		}
		
		tvFriendName.setText(fl.name);
		switchPush.setFocusable(false);
		switchPush.setFocusableInTouchMode(false);
		switchPush.setOnCheckedChangeListener(this);
		switchPush.setTag(fl);
		
		if (fl.following != null) {
			if (fl.following.equals("Y")) {
				switchPush.setChecked(true);
			} else {
				switchPush.setChecked(false);
			}
			
		}
		
		return(v);
	}


	@Override
	public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
		
		boolean b;
		Switch sw = (Switch) buttonView;
		FriendsList fl = (FriendsList) sw.getTag();
		
		MyLog.d(tag, "onCheckChanged(name=" + fl.name + ")");
		
		if (fl.following.equals("Y")) {
			b = true;
		} else {
			b = false;
		}
		
		if (b != isChecked) {
			if (isChecked == true) {
				fl.following = "Y";
			} else {
				fl.following = "N";
			}
			
			this.dbm.updateRecordByPrimarykey("friends_list", fl, true);
			AutoLikerService aService = AutoLikerService.getInstance();
			aService.updateFriendsList(fl.id, fl);
		}
		
	}

}
